﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Simulator;

using ELW.Library.Math;
using ELW.Library.Math.Exceptions;
using ELW.Library.Math.Expressions;
using ELW.Library.Math.Tools;

namespace ModelConfigurator
{
    public partial class FormDecision : FormBase
    {
        /// <summary>
        /// Блок решения, который редактируем
        /// </summary>
        public Decision Edited { get; set; }
        private int falsePort;//порт ЛОЖЬ
        private int truePort;//порт ИСТИНА
        private int hiddenPort;//неподключенных порт

        public FormDecision()
        {
            InitializeComponent();
        }

        private void FormDecision_Load(object sender, EventArgs e)
        {
            //заполним текстовое поле
            try
            {
                textBox2.Text = String.Format("{0}", ToolsHelper.Decompiler.Decompile(Edited.CompareCompiledString));
            }
            catch
            {
                errorProvider1.SetError(textBox2, "Неверное выражение");
            }
            //настроим радио-кнопки
            if (Edited.PortMap[0] == 't')
                radioButtonTop.Checked = true;
            if (Edited.PortMap[1] == 't')
                radioButtonMid.Checked = true;
            if (Edited.PortMap[2] == 't')
                radioButtonBottom.Checked = true;

            if (Edited.PortMap[0] == 'f')
                radioButtonTop.Checked = false;
            if (Edited.PortMap[1] == 'f')
                radioButtonMid.Checked = false;
            if (Edited.PortMap[2] == 'f')
                radioButtonBottom.Checked = false;
            //найдем, какой порт отвечает за 'f'
            falsePort = Edited.PortMap.FindIndex(delegate(char c) { return (c == 'f'); });
            //найдем, какой порт отвечает за 't'
            truePort = Edited.PortMap.FindIndex(delegate(char c) { return (c == 't'); });
            //найдем, какой порт отвечает за 'h'
            hiddenPort = Edited.PortMap.FindIndex(delegate(char c) { return (c == 'h'); });
            SetRadioButtonTextes();
        }
        private void SetRadioButtonTextes()
        {
            radioButtonTop.Text = "Верхний";
            radioButtonMid.Text = "Правый";
            radioButtonBottom.Text = "Нижний";
            switch (hiddenPort)
            {
                case 0:
                    radioButtonTop.Text += " -";
                    break;
                case 1:
                    radioButtonMid.Text += " -";
                    break;
                case 2:
                    radioButtonBottom.Text += " -";
                    break;
            }
        }
        private void buttonOK_Click(object sender, EventArgs e)
        {
            //проверим корректность строки парсера
            if (txtCheck(textBox2))
            {
                Apply();
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
        }

        private void Apply()
        {
            //применим настройки к Edited
            Edited.CompareString = textBox2.Text;
            //прочитаем радио-кнопки
            int port = 0;
            if (radioButtonBottom.Checked)
                port = 2;
            if (radioButtonMid.Checked)
                port = 1;

            if (port == falsePort)//если порт true это прежний порт false
            {
                Edited.PortMap[port] = 't';
                if (truePort != -1)
                {
                    Edited.PortMap[truePort] = 'f';//прежний порт true стал портом false
                }
            }
            else if (port == hiddenPort)//если порт true это прежний порт hidden
            {
                Edited.PortMap[port] = 't';
                if (truePort != -1)
                {
                    Edited.PortMap[truePort] = 'h';//прежний порт true стал портом hidden
                }
            }
            //иначе все оставим как есть
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
            this.Close();
        }

        private void textBox2_Leave(object sender, EventArgs e)
        {
            if (txtCheck(textBox2))
                Edited.CompareString = textBox2.Text;
        }

        /// <summary>
        /// Проверка содержимого текстового поля на корректность выражения для парсера
        /// </summary>
        /// <param name="txt"></param>
        /// <returns></returns>
        private bool txtCheck(TextBox txt)
        {
            bool b = false;
            errorProvider1.Clear();
            try
            {
                string s = txt.Text;
                //пробуем посчитать
                List<VariableValue> variables = new List<VariableValue>();
                variables.Add(new VariableValue(0, "C"));
                variables.Add(new VariableValue(0, "Q"));

                PreparedExpression preparedExpression = ToolsHelper.Parser.Parse(s);
                CompiledExpression cmp = ToolsHelper.Compiler.Compile(preparedExpression);
                ToolsHelper.Calculator.Calculate(cmp, variables);

                b = true;
            }
            catch (CompilerSyntaxException ex)
            {
                errorProvider1.SetError(txt, String.Format("Ошибка компиляции: {0}", ex.Message));
            }
            catch (MathProcessorException ex)
            {
                errorProvider1.SetError(txt, String.Format("Ошибка: {0}", ex.Message));
            }
            catch (ArgumentException)
            {
                errorProvider1.SetError(txt, "Неверно введенные данные.");
            }
            catch (Exception)
            {
                errorProvider1.SetError(txt, "Непредвиденная ошибка.");
                throw;
            }
            return b;
        }

        private void buttonHelp_Click(object sender, EventArgs e)
        {
            string openCHMFile = Application.StartupPath + "\\Справка SAPR-SIM.chm";
            try
            {
                if (!System.IO.File.Exists(openCHMFile))
                    System.IO.File.WriteAllBytes(openCHMFile, global::ModelConfigurator.Properties.Resources.Справка_SAPR_SIM);
            }
            catch
            {
                //если файл есть он не перепишется
            }
            helpProvider1.HelpNamespace = openCHMFile;
            Help.ShowHelp(this, this.helpProvider1.HelpNamespace, HelpNavigator.Topic, "module_2_6_4.htm");
        }
    }
}
